package com.xiaoxi.userserver.controller.user;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.xiaoxi.common.constant.enumeration.statuscode.system.LoginSystemEnums;
import com.xiaoxi.logaspectcommon.common.annotation.OperationLog;
import com.xiaoxi.logaspectcommon.common.constant.OperationConstants;
import com.xiaoxi.common.constant.enumeration.statuscode.user.LoginUserEnums;
import com.xiaoxi.common.exception.BMSException;
import com.xiaoxi.common.response.ApiResponse;
import com.xiaoxi.common.util.AuthUtils;
import com.xiaoxi.common.util.ExcelUtils;
import com.xiaoxi.common.util.RSAUtils;
import com.xiaoxi.domain.user.BMSUserDetail;
import com.xiaoxi.service.circulation.ExportDataToExcelService;
import com.xiaoxi.userserver.domain.dto.user.BMSUserDetailDTO;
import com.xiaoxi.userserver.domain.vo.user.BMSUserDetailVO;
import com.xiaoxi.userserver.service.user.BMSUserDetailService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Pageable;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author xiaoxi
 * @version 1.0
 * @date 2022/6/22 23:09
 */
@RestController
@RequestMapping("/userDetail/api/v1")
@Slf4j
public class BMSUserDetailController {

    @Resource
    private BMSUserDetailService bmsUserDetailService;

    @Resource
    private PasswordEncoder passwordEncoder;

    @Resource(name = "bmsUserDetailServiceImpl")
    private ExportDataToExcelService exportDataToExcelService;

    @Value("${bms.xiaoxi.RSA-private-key}")
    private String rsaPrivateKey;

    /**
     * 获取用户列表
     *
     * @param bmsUserDetailDTO 查询条件
     * @param pageable         分页
     * @return
     */
    @OperationLog(operation = OperationConstants.CODE_QUERY_PAGE)
    @GetMapping("getAllUserInfo")
    public ApiResponse getAllUserInfo(BMSUserDetailDTO bmsUserDetailDTO, Pageable pageable) {

        IPage<BMSUserDetailVO> bmsUserDetailVOIPage = bmsUserDetailService.getAllUserInfo(bmsUserDetailDTO, pageable);
        return ApiResponse.ofSuccess(bmsUserDetailVOIPage);

    }

    /**
     * 获取用户详情
     *
     * @param userDetailId 用户详情id
     * @return
     */
    @OperationLog(operation = OperationConstants.CODE_QUERY_ONE)
    @GetMapping("getUserInfoByUserDetailId/{userDetailId}")
    public ApiResponse getUserInfoByUserDetailId(@PathVariable Long userDetailId) {

        BMSUserDetailVO bmsUserDetailVO = null;
        try {
            bmsUserDetailVO = bmsUserDetailService.getUserInfoByUserDetailId(userDetailId);
        } catch (BMSException e) {
            log.error("未找到该用户:{}", e.getMessage());
            return ApiResponse.ofException(e);
        }

        return ApiResponse.ofSuccess(bmsUserDetailVO);

    }

    /**
     * 获取当前用户详情
     *
     * @return
     */
    @OperationLog(operation = OperationConstants.CODE_QUERY_ONE)
    @GetMapping("getCurrentUserInfo")
    public ApiResponse getCurrentUserInfo() {

        BMSUserDetailVO bmsUserDetailVO = null;
        try {
            bmsUserDetailVO = bmsUserDetailService.getCurrentUserInfo();
        } catch (BMSException e) {
            log.error("未找到该用户:{}", e.getMessage());
            return ApiResponse.ofException(e);
        }

        return ApiResponse.ofSuccess(bmsUserDetailVO);

    }


    /**
     * 编辑当前用户
     *
     * @return
     */
    @OperationLog(operation = OperationConstants.CODE_MODIFY)
    @PostMapping("editCurrentUserInfo")
    public ApiResponse editCurrentUserInfo(@RequestBody BMSUserDetailVO bmsUserDetailVO) {

        BMSUserDetail bmsUserDetail = null;
        try {
            bmsUserDetail = bmsUserDetailService.editCurrentUserInfo(bmsUserDetailVO);
        } catch (BMSException bmsException) {
            log.error("出现异常：{}", bmsException.getMessage());
            return ApiResponse.ofException(bmsException);
        }

        return ApiResponse.ofSuccess(bmsUserDetail);
    }


    /**
     * 更新用户
     *
     * @param bmsUserDetailVO 用户修改信息
     * @return
     */
    @OperationLog(operation = OperationConstants.CODE_MODIFY)
    @PostMapping("updateUserInfo")
    public ApiResponse updateUserInfo(@RequestBody BMSUserDetailVO bmsUserDetailVO) {

        try {
            // 1. 比对密码是否输入正确
            String myPassword = RSAUtils.decryptByPrivateKey(bmsUserDetailVO.getBmsUserPasswordChangeVO().getMyPassword(), rsaPrivateKey);
            if (passwordEncoder.matches(myPassword, AuthUtils.getCurrentUser().getPassword())) {
                bmsUserDetailService.updateUserInfo(bmsUserDetailVO);
            } else {
                // 密码错误 更新失败
                return ApiResponse.ofEnum(LoginUserEnums.PASSWORD_MISTAKE);
            }
        } catch (BMSException e) {
            log.error("出现异常：{}", e.getMessage());
            return ApiResponse.ofException(e);
        } catch (Exception e) {
            log.error("密钥异常：{}", e.getMessage());
            return ApiResponse.ofEnum(LoginSystemEnums.PRIVATE_KEY_FAIL);
        }

        return ApiResponse.ofSuccess(bmsUserDetailVO);

    }

    /**
     * 创建用户
     *
     * @param bmsUserDetailVO 用户基本信息
     * @return
     */
    @OperationLog(operation = OperationConstants.CODE_CREATE)
    @PostMapping("createUserInfo")
    public ApiResponse createUserInfo(@RequestBody BMSUserDetailVO bmsUserDetailVO) {

        try {
            bmsUserDetailService.createUserInfo(bmsUserDetailVO);
        } catch (BMSException e) {
            log.error("出现异常：{}", e.getMessage());
            return ApiResponse.ofException(e);
        }

        return ApiResponse.ofSuccess(bmsUserDetailVO);

    }


    /**
     * 导出用户
     *
     * @param bmsUserDetailDTO 查询条件
     * @return
     */
    @GetMapping("exportUserInfo")
    public void exportUserInfo(BMSUserDetailDTO bmsUserDetailDTO, HttpServletRequest request, HttpServletResponse response) {

        try {
            ExcelUtils.exportExcel(request, response, "用户详情表.xls", exportDataToExcelService, bmsUserDetailDTO);
        } catch (BMSException e) {
            throw new RuntimeException(e);
        }

    }


}
